#ifndef RENDERER_H
#define RENDERER_H

#include <GL/glew.h>
#include <SFML/Window.hpp>

#include "../core/glm.hpp"
#include "../core/Mesh.hpp"
#include "../core/Visitor.h"

class GameObject;
class World;
class Camera;
class Light;
class Texture;
class Collider;
class ShaderProgram;
class Player;
class Asteroid;
class Explosion;
class Renderer;

class Renderer : public Visitor {
    private:
        sf::Window* window;

        // the shader wrapper
        ShaderProgram* program;
        // shader input locations
        GLuint projectionLoc, viewLoc, modelLoc, lightLoc, timeLoc; 	// uniform locations
        GLuint verticesLoc, normalsLoc, uvsLoc;		// attribute locations
        GLuint colorMapLoc;

        // buffered variables
        float time;
        glm::mat4 projection, view, model;
        glm::vec3 light;
        GLuint colorMap;

    public:
        Renderer(sf::Window* aWindow);
        virtual ~Renderer();

        void use(ShaderProgram* program);

        void setProjection(glm::mat4 aProjection);

        void setView(glm::mat4 aView);
        glm::mat4 getView();

        void setModel(glm::mat4 aModel);

        void setTime(float aTime);
        void setLight(glm::vec3 aLight);
        void setColorMap(Texture* aColorMap);
        void drawMesh(Mesh*);  // drawing mesh, all other uniforms etc should be allready available

        void visit(World*);
        void visit(Light*);
        void visit(Camera*);
        void visit(GameObject*);
        void visit(Collider*);
        void visit(Asteroid*);
        void visit(Rocket*);
        void visit(Explosion*);

    private:
        void findLocations();
};

#endif // RENDERER_H
